import {COLOR_PIE, COLOR_PIE_16, FONT_FAMILY} from '../theme/default';

// 声明所需变量
let canvas, ctx;
// 图表属性
let cWidth, cHeight, cMargin, cSpace;
// 饼状图属性
let radius, innerRadius, ox, oy;//半径 圆心
let tWidth, tHeight;//图例宽高
let posX, posY, textX, textY;
let startAngle, endAngle;
let totleNb;
// 运动相关变量
let ctr, numctr, speed;

//线条和文字
let lineStartAngle, line, textPadding, textMoveDis;

let new_data_arr = [], totalYNomber, rotateAngle;

class PieChart {
  constructor() {
    this.dataArr = [];
  }

  init = () => {
    let parent = document.getElementById(this.container);
    parent.innerHTML = '';
    let width = parent.offsetWidth;
    if (!this.forceFit) {
      width = this.width || 375;
    }
    this.height = Math.max(this.height, this.dataArr.length * 25);
    canvas = document.createElement('canvas');
    parent.appendChild(canvas);
    if (canvas && canvas.getContext) {
      ctx = canvas.getContext('2d');
    }
    cMargin = 20;
    cSpace = 40;

    //将传入的数据转化百分比
    totleNb = 0;
    new_data_arr = [];
    for (let i = 0; i < this.dataArr.length; i++) {
      const item = this.dataArr[i];
      totleNb += item[this.field];
      const text = this.getLegendText(item);
      cSpace = Math.max(cSpace, ctx.measureText(text).width);
    }
    new_data_arr = this.dataArr.map(item => (item[this.field] / totleNb));

    canvas.width = width * 2;
    canvas.height = this.height * 2;
    canvas.style.height = canvas.height / 2 + 'px';
    canvas.style.width = canvas.width / 2 + 'px';
    cHeight = canvas.height;
    cWidth = canvas.width - cMargin * 3;

    //饼状图信息
    radius = cHeight * this.coord.radius / 2;  //半径
    innerRadius = cHeight * this.coord.innerRadius / 2;
    ox = canvas.width / 2 + cSpace + cMargin * 2;  //圆心
    oy = canvas.height / 2;
    tWidth = tHeight = 10; //图例宽和高
    posX = cMargin;
    posY = (this.height * 2 - this.dataArr.length * 50) / 2;
    textX = posX + tWidth + 15;
    textY = posY + 18;
    startAngle = endAngle = 90 * Math.PI / 180; //起始弧度 结束弧度
    rotateAngle = 0; //整体旋转的弧度

    totalYNomber = 10;
    // 运动相关
    ctr = 1;//初始步骤
    numctr = 40;//步骤
    speed = 1; //毫秒 timer速度

    //指示线 和 文字
    lineStartAngle = -startAngle;
    line = 20;         //画线的时候超出半径的一段线长
    textPadding = 3;  //文字与线之间的间距
    textMoveDis = 200; //文字运动开始的间距
  };

  drawMarkers = () => {
    ctx.textAlign = 'left';
    const h = 50;
    for (let i = 0; i < this.dataArr.length; i++) {
      //绘制比例图及文字
      ctx.fillStyle = this.colors[i];
      ctx.fillRect(posX, posY + h * i, tWidth, tHeight);
      ctx.moveTo(posX, posY + h * i);
      ctx.font = `${24}px ${FONT_FAMILY}`;    //斜体 30像素 微软雅黑字体
      ctx.fillStyle = 'rgba(0,0,0,0.5)'; //'#000000';
      let percent = this.getLegendText(this.dataArr[i]);
      ctx.fillText(percent, textX, textY + h * i);
    }
  };

  pieDraw = () => {
    for (let n = 0; n < this.dataArr.length; n++) {
      ctx.fillStyle = ctx.strokeStyle = this.colors[n];
      ctx.lineWidth = 1;
      let step = new_data_arr[n] * Math.PI * 2; //旋转弧度
      let lineAngle = lineStartAngle + step / 2;   //计算线的角度
      lineStartAngle += step;//结束弧度

      ctx.beginPath();
      let x0 = ox + radius * Math.cos(lineAngle),//圆弧上线与圆相交点的x坐标
        y0 = oy + radius * Math.sin(lineAngle),//圆弧上线与圆相交点的y坐标
        x1 = ox + (radius + line) * Math.cos(lineAngle),//圆弧上线与圆相交点的x坐标
        y1 = oy + (radius + line) * Math.sin(lineAngle),//圆弧上线与圆相交点的y坐标
        x2 = x1,//转折点的x坐标
        y2 = y1;

      ctx.moveTo(x0, y0);
      //对x1/y1进行处理，来实现折线的运动
      let yMove = y0 + (y1 - y0) * ctr / numctr;
      ctx.lineTo(x1, yMove);
      if (x1 <= x0) {
        ctx.textAlign = 'right';
        ctx.fillText(
          this.dataArr[n][this.item] + ':' + parseInt(100 * new_data_arr[n]) + '%',
          x2 - textPadding - textMoveDis * (numctr - ctr) / numctr, y2 - textPadding + 6);
      } else {
        ctx.textAlign = 'left';
        ctx.fillText(
          this.dataArr[n][this.item] + ':' + parseInt(100 * new_data_arr[n]) + '%',
          x2 + textPadding + textMoveDis * (numctr - ctr) / numctr, y2 - textPadding + 6);
      }
      ctx.stroke();
    }

    //设置旋转
    ctx.save();
    ctx.translate(ox, oy);
    ctx.rotate((Math.PI * 2 / numctr) * ctr / 2);

    for (let j = 0; j < this.dataArr.length; j++) {
      //绘制饼图
      endAngle = endAngle + new_data_arr[j] * ctr / numctr * Math.PI * 2; //结束弧度
      ctx.beginPath();
      ctx.moveTo(0, 0); //移动到到圆心
      ctx.arc(0, 0, radius * ctr / numctr, startAngle, endAngle, false); //绘制圆弧
      ctx.fillStyle = this.colors[j];
      ctx.closePath();
      ctx.fill();
      ctx.globalAlpha = 1;

      startAngle = endAngle; //设置起始弧度
      if (j === this.dataArr.length - 1) {
        startAngle = endAngle = 90 * Math.PI / 180; //起始弧度 结束弧度
      }
    }
    if (innerRadius > 1) {
      ctx.beginPath();
      ctx.moveTo(24, 24);
      ctx.arc(0, 0, innerRadius, 0, Math.PI * 2, true);
      ctx.closePath();
      ctx.fillStyle = 'rgba(255,255,255,1)';
      ctx.fill();
    }

    ctx.restore();

    if (ctr < numctr) {
      ctr++;
      setTimeout(() => {
        ctx.clearRect(-canvas.width, -canvas.height, canvas.width * 2, canvas.height * 2);
        this.drawMarkers();
        this.pieDraw();
      }, speed *= 1.085);
    }
  };

  source = (data = [], config = {}) => {
    this.dataArr = data || [];
    this.colors = this.dataArr.length > 8 ? COLOR_PIE_16 : COLOR_PIE;
    this.config = Object.assign({}, this.config, config);
    return this;
  };
  config = (config = {}) => {
    this.container = config.container;
    this.pixelRatio = window.devicePixelRatio;
    this.height = config.height || 400;
    this.forceFit = !!config.forceFit;
    this.item = config.item || 'item';
    this.field = config.field || 'field';
    let coord = config.coord || {};
    this.coord = {
      radius: coord.radius || 0.5,
      innerRadius: coord.innerRadius || 0.2
    };
    const legend = config.legend || {};
    this.legend = {
      field: this.item,
      formatter: legend.formatter
    };
    return this;
  };

  getLegendText = (item, field = this.legend.field,) => {
    let formatter = this.legend.formatter;
    let text = item[field];
    if (typeof formatter === 'function') {
      text = formatter(item, item[field], item[this.field]);
    }
    return text;
  };

  render = () => {
    this.init();
    this.drawMarkers();
    this.pieDraw();
  }
}

export default (config = {}) => new PieChart().config(config);
